package cn.kent.ws;


import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint(value = "/ws/{userId}")
@Component
@Slf4j
public class WebSocket {
    private static ConcurrentHashMap<String, WebSocket> webSocketMapJs = new ConcurrentHashMap<>();
    //实例一个session，这个session是websocket的session
    private Session session;

    @Value("${websocket.gzip}")
    private static Boolean wsGzip = false;

   // @Autowired
    //private ReportTaskResult reportTaskResult;

    //新增一个方法用于主动向客户端发送消息
    public static void sendMessage(Object message, String userId) {
        WebSocket webSocket = webSocketMapJs.get(userId);
        if (webSocket != null) {
            if (wsGzip) {
                //try {
                //   // webSocket.session.getBasicRemote().sendBinary(ByteBuffer.wrap(GZIPUtils.compress(String.valueOf(message))));
                //    //log.debug("【websocket消息】发送消息成功,用户=" + userId + ",消息内容" + message.toString());
                //} catch (IOException e) {
                //    e.printStackTrace();
                //}
            } else {
                try {
                    webSocket.session.getBasicRemote().sendText(JSONUtil.toJsonStr(message));
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    public static void sendMessage(Object message) {
        webSocketMapJs.forEach((k, v) -> {
            synchronized (v) {
                sendMessage(message, k);
            }
        });
    }


    //前端请求时一个websocket时
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        this.session = session;
        webSocketMapJs.put(userId, this);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("type", "CONNECT_SUCCESS");
        sendMessage(jsonObject.toJSONString(1), userId);
        log.warn("【websocket消息】有新的连接,连接id:{}  总数：{}" , userId ,webSocketMapJs.size());
        // 启动心跳定时器
        startHeartbeatTimer(userId);
    }

    private void startHeartbeatTimer(String userId) {
        new Thread(() -> {
            while (webSocketMapJs.containsKey(userId)) {
                try {
                    Thread.sleep(30000); // 每30秒发送一次心跳
                    sendMessage("{\"type\":\"ping\"}", userId);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    //前端关闭时一个websocket时
    @OnClose
    public void onClose(@PathParam("userId") String userId) {
        webSocketMapJs.remove(userId);
        log.error("【websocket消息】连接断开,总数:" + webSocketMapJs.size());
    }

    //前端向后端发送消息
    @OnMessage
    public void onMessage(String message) {
        log.info("【websocket消息】收到客户端发来的消息:" + message);
        JSONObject jsonObject = null;
        try {
            jsonObject = JSONUtil.parseObj(message);
        } catch (Exception exception) {
            log.error("解析消息失败: {}", exception.getMessage());
            return;
        }
        if (jsonObject != null && jsonObject.get("method") != null && !jsonObject.get("method").equals("ping")) {
            String result = null;
            try {
                //result =  NavigationApiUtil.getInstance().getnApiLibrary().Handle(message);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            log.warn("\n执行==================================== \n 参数：{} \n 结果:{} \n执行==================================== end!", message, result);
            //reportTaskResult.execute(result);
            // 发送返回结果
//            sendMessage(result);
            // 发送pong响应
            sendMessage("{\"type\":\"pong\"}");
        } else {
            log.info("【websocket消息】收到客户端发来的ping消息:" + message);
        }
    }
    @OnError
    public void onError(Throwable error) {
        log.error("WebSocket错误: {}", error.getMessage());
    }
}